package com.easyJava.builder;

import com.easyJava.bean.Constants;
import com.easyJava.bean.FieldInfo;
import com.easyJava.bean.TableInfo;
import com.easyJava.utils.BufferedWriterUtils;
import com.easyJava.utils.LocalDateTimeUtils;
import com.easyJava.utils.LocalDateUtils;
import com.easyJava.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class BuildQuery {
    public static void execute(TableInfo tableInfo){
        File folder = new File(Constants.PATH_QUERY);
        folder.mkdirs();
        String beanQueryName = tableInfo.getBeanName() + Constants.SUFFIX_BEAN_QUERY;
        File file = new File(folder, beanQueryName + Constants.FILE_SUFFIX_JAVA);

        try (
            OutputStream out = new FileOutputStream(file);
            OutputStreamWriter ow = new OutputStreamWriter(out, StandardCharsets.UTF_8);
            BufferedWriter bufferedWriter = new BufferedWriter(ow);
        ){
            BufferedWriterUtils bw = new BufferedWriterUtils(bufferedWriter);

            //引包
            bw.write("package " + Constants.PACKAGE_QUERY + ";");
            bw.newLine();

            //根据需要引入时间和浮点数类
            importRequirePackage(tableInfo, bw);

            //生成注释
            BuildComment.createClassComment(bw, tableInfo.getComment());
            //Query类
            bw.write("public class " + beanQueryName + " extends BaseQuery{");

            //生成所有属性集合
            List<FieldInfo> allFieldList = new ArrayList<>(tableInfo.getFieldList());
            allFieldList.addAll(tableInfo.getExtendFieldList());

            //生成属性
            generateField(bw, allFieldList);

            //生成setter getter方法
            generateSetAndGet(bw, allFieldList);

            bw.write("}");
            bw.flush();
        }catch (Exception e){
            log.error("创建query对象失败:{}", e);
        }


    }

    private static void generateSetAndGet(BufferedWriterUtils bw, List<FieldInfo> allFieldList) throws IOException {
        for(FieldInfo fieldInfo : allFieldList){
            bw.write("\tpublic void set" + StringUtils.upperFirstChar(fieldInfo.getBeanFieldName()) + "(" + fieldInfo.getJavaType() + " " + fieldInfo.getBeanFieldName() + "){");
            bw.write("\t\tthis." + fieldInfo.getBeanFieldName() + " = " + fieldInfo.getBeanFieldName() + ";");
            bw.write("\t}");
            bw.newLine();

            bw.write("\tpublic " + fieldInfo.getJavaType() + " get" + StringUtils.upperFirstChar(fieldInfo.getBeanFieldName()) + "(){");
            bw.write("\t\treturn this." + fieldInfo.getBeanFieldName() + ";");
            bw.write("\t}");
            bw.newLine();
        }
    }

    private static void generateField(BufferedWriterUtils bw, List<FieldInfo> allFieldList) throws IOException {
        for(FieldInfo fieldInfo : allFieldList){
            BuildComment.createFieldComment(bw, fieldInfo.getComment());
            BuildAnnotation.createQueryFieldAnnotation(bw, fieldInfo);
            bw.write("\tprivate " + fieldInfo.getJavaType() + " " + fieldInfo.getBeanFieldName() + ";");
            bw.newLine();
        }
    }

    private static void importRequirePackage(TableInfo tableInfo, BufferedWriterUtils bw) throws IOException {
        if(tableInfo.isHaveDate()){
            bw.write("import java.time.LocalDate;");
            bw.write(Constants.DATE_FORMAT_PACKAGE);
        }
        if(tableInfo.isHaveDateTime()){
            bw.write("import java.time.LocalDateTime;");
            bw.write(Constants.DATE_FORMAT_PACKAGE);
        }
        if(tableInfo.isHaveBigDecimal()){
            bw.write("import java.math.BigDecimal;");
        }
    }
}
